home *** CD-ROM | disk | FTP | other *** search
- #define STRICT
-
- // Includes standard Windows
- #include <windows.h>
- #include <windowsx.h>
- #include <time.h>
- #include <stdlib.h>
- #include <malloc.h>
- #include <memory.h>
- #include <stdio.h>
-
- // Includes D3D
- #define D3D_OVERLOADS
- #include <ddraw.h>
- #include <d3d.h>
- #include <d3dx.h>
-
- // Includes utilitaires D3D
- #include "d3dmath.h"
- #include "d3dutil.h"
- #include "D3DEnum.h"
-
- // Ids Resources
- #include "resource.h"
-
- // Constantes
- #include "const.h"
-
- // Types
- #include "types.h"
-
- // Variables globales projet
- #include "vars.h"
-
- // Prototypes fonctions autres modules
- #include "proto.h"
-
- // Macros
- #include "macros.h"
-
- //-----------------------------------------------------------------------------
- // Name: EnumZBufferCallback()
- // Desc: Enumeration function to report valid pixel formats for z-buffers.
- //-----------------------------------------------------------------------------
- static HRESULT WINAPI hrEnumZBufferCallback( DDPIXELFORMAT* pddpf,
- VOID* pddpfDesired )
- {
- #ifndef NO3D
- // For this tutorial, we are only interested in z-buffers, so ignore any
- // other formats (e.g. DDPF_STENCILBUFFER) that get enumerated. An app
- // could also check the depth of the z-buffer (16-bit, etc,) and make a
- // choice based on that, as well. For this tutorial, we'll take the first
- // one we get.
- if( pddpf->dwFlags == DDPF_ZBUFFER )
- {
- memcpy( pddpfDesired, pddpf, sizeof(DDPIXELFORMAT) );
- vTrace("ZBuffer depth : %d bit", ((DDPIXELFORMAT *) pddpfDesired) -> dwZBufferBitDepth);
-
- // Return with D3DENUMRET_CANCEL to end the search.
- return D3DENUMRET_CANCEL;
- }
- #endif
- // Return with D3DENUMRET_OK to continue the search.
- return D3DENUMRET_OK;
- }
-
- ////////////////////////////////////////////////////////////////////////////
- HRESULT hrPreInitD3D(void)
- {
- HRESULT hr = S_OK;
-
- #ifndef NO3D
- // Create DirectDraw interface.
- vTrace("Création interface DirectDraw7");
- hr = DirectDrawCreateEx (NULL, (void **)&lpDD, IID_IDirectDraw7, NULL);
- if( FAILED( hr ) )
- return hr;
-
- // Get an IDirect3D7 interface
- vTrace("Définition interface Direct3D V7");
- hr = lpDD->QueryInterface (IID_IDirect3D7, (void **)&lpD3D);
- #endif
-
- return hr;
- }
-
- ////////////////////////////////////////////////////////////////////////////
- HRESULT hrInitD3D(HWND hWnd, const GUID* pDeviceGUID)
- {
- HRESULT hr = S_OK;
- #ifndef NO3D
-
- // Set the Windows cooperative level. The flag DDSCL_NORMAL specifies windowed mode.
- vTrace("Demande mode fenêtré (mode coopératif)");
- hr = lpDD->SetCooperativeLevel( hWnd, DDSCL_NORMAL );
- if( FAILED( hr ) )
- return hr;
-
- // Initialize a surface description structure for the Render surface.
- vTrace("Initialisation du descripteur de surface Render");
- ZeroMemory( &ddsd, sizeof(DDSURFACEDESC2) );
- ddsd.dwSize = sizeof(DDSURFACEDESC2);
- ddsd.dwFlags = DDSD_CAPS;
- ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
-
- // Create the Render surface.
- vTrace("Création de la surface Render");
- hr = lpDD->CreateSurface( &ddsd, &lpddsRender, NULL );
- if( FAILED( hr ) ) return hr;
-
- // Setup a surface description to create a backbuffer with dimensions equal to our window size.
- vTrace("Initialisation du descripteur de surface BackBuffer");
- ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
- ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
-
- // Set the dimensions of the backbuffer. Note that if our window changes
- // size, we need to destroy this surface and create a new one.
- vTrace("Dimensionnement de la surface BackBuffer");
- GetClientRect( hWnd, &sRectangle );
- ClientToScreen( hWnd, (POINT*)&sRectangle.left );
- ClientToScreen( hWnd, (POINT*)&sRectangle.right );
- ddsd.dwWidth = sRectangle.right - sRectangle.left;
- ddsd.dwHeight = sRectangle.bottom - sRectangle.top;
-
- // Create the backbuffer.
- vTrace("Création de la la surface BackBuffer");
- hr = lpDD->CreateSurface( &ddsd, &lpddsBackBuffer, NULL );
- if( FAILED( hr ) )
- return hr;
-
- // Create a clipper object which handles all our clipping for cases when
- // our window is partially obscured by other windows.
- vTrace("Création du clipper");
- LPDIRECTDRAWCLIPPER pcClipper;
- hr = lpDD->CreateClipper( 0, &pcClipper, NULL );
- if( FAILED( hr ) )
- return hr;
-
- // Associate the clipper with our window.
- vTrace("Association clipper <-> fenêtre");
- pcClipper->SetHWnd( 0, hWnd );
- lpddsRender->SetClipper( pcClipper );
- pcClipper->Release();
-
- // Create the z-buffer AFTER creating the backbuffer and BEFORE creating the d3ddevice.
- DDPIXELFORMAT ddpfZBuffer;
- lpD3D->EnumZBufferFormats( *pDeviceGUID,
- hrEnumZBufferCallback, (VOID*)&ddpfZBuffer );
-
- // If we found a good zbuffer format, then the dwSize field will be
- // properly set during enumeration. Else, we have a problem and will exit.
- if( sizeof(DDPIXELFORMAT) != ddpfZBuffer.dwSize )
- return E_FAIL;
-
- // Get z-buffer dimensions from the render target
- // Setup the surface desc for the z-buffer.
- ddsd.dwFlags = DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT;
- ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
- ddsd.dwWidth = sRectangle.right - sRectangle.left;
- ddsd.dwHeight = sRectangle.bottom - sRectangle.top;
- memcpy( &ddsd.ddpfPixelFormat, &ddpfZBuffer, sizeof(DDPIXELFORMAT) );
-
- // For hardware devices, the z-buffer should be in video memory. For
- // software devices, create the z-buffer in system memory
- if( IsEqualIID( *pDeviceGUID, IID_IDirect3DHALDevice ) ||
- IsEqualIID( *pDeviceGUID, IID_IDirect3DTnLHalDevice ) )
- ddsd.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
- else
- ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
-
- // Create and attach a z-buffer. Real apps should be able to handle an
- // error here (DDERR_OUTOFVIDEOMEMORY may be encountered). For this
- // tutorial, though, we are simply going to exit ungracefully.
- if( FAILED( hr = lpDD->CreateSurface( &ddsd, &g_pddsZBuffer, NULL ) ) )
- return hr;
-
- // Attach the z-buffer to the back buffer.
- if( FAILED( hr = lpddsBackBuffer->AddAttachedSurface( g_pddsZBuffer ) ) )
- return hr;
-
- // Check that we are NOT in a palettized display.
- vTrace("Vérification true color");
- ddsd.dwSize = sizeof(DDSURFACEDESC2);
- lpDD->GetDisplayMode( &ddsd );
- if( ddsd.ddpfPixelFormat.dwRGBBitCount <= 8 )
- return DDERR_INVALIDMODE;
-
- // Create the device (hardware renderer).
- vTrace("Création device 3D");
- hr = lpD3D->CreateDevice( *pDeviceGUID, lpddsBackBuffer,
- &lpd3dDevice );
- if( FAILED( hr ) )
- {
- vTrace("*** E0007 : Echec création device 3D.");
- return hr;
- }
- else
- vTrace("Succès création device 3D.");
-
- // Store device ID (to reuse later when resizing the window)
- gDeviceGUID = *pDeviceGUID;
-
- // Create the viewport
- vTrace("Création viewport");
- DWORD dwRenderWidth = sRectangle.right - sRectangle.left;
- DWORD dwRenderHeight = sRectangle.bottom - sRectangle.top;
- D3DVIEWPORT7 vp = { 0, 0, dwRenderWidth, dwRenderHeight, 0.0f, 1.0f };
- hr = lpd3dDevice->SetViewport( &vp );
- if( FAILED( hr ) )
- return hr;
-
- vTrace("Initialisation D3D ok.");
- #endif
- return hr;
- }
-
- HRESULT hrCloseD3D(BOOL bFull)
- {
- #ifndef NO3D
-
- // Release the DDraw and D3D objects used by the app
- if( g_pddsZBuffer ) g_pddsZBuffer->Release();
- if( lpddsBackBuffer ) lpddsBackBuffer->Release();
- if( lpddsRender ) lpddsRender->Release();
-
- // Do a safe check for releasing the D3DDEVICE. RefCount should be zero.
- if( lpd3dDevice )
- if( 0 < lpd3dDevice->Release() )
- return E_FAIL;
-
- g_pddsZBuffer = NULL;
- lpddsBackBuffer = NULL;
- lpddsRender = NULL;
- lpd3dDevice = NULL;
-
- if (bFull)
- {
- D3DXUninitialize();
- if( lpD3D )
- lpD3D->Release();
-
- // Do a safe check for releasing DDRAW. RefCount should be zero.
- if( lpDD )
- if( 0 < lpDD->Release() )
- return E_FAIL;
-
- lpD3D = NULL;
- lpDD = NULL;
- }
-
- #endif
-
- return 0;
- }
-
- // Show the frame on the Render surface
- HRESULT hrShowFrame(void)
- {
- #ifndef NO3D
- if( NULL == lpddsRender )
- return E_FAIL;
-
- // Perform a blit from the backbuffer to the correct position on the Render surface
- return lpddsRender->Blt( &sRectangle, lpddsBackBuffer,
- NULL, DDBLT_WAIT, NULL );
- #else
- return S_OK;
- #endif
- }
-
- // Checks for lost surfaces and restores them if lost.
- HRESULT hrRestoreSurfaces(void)
- {
- #ifndef NO3D
- // Check/restore the Render surface
- if( lpddsRender )
- if( lpddsRender->IsLost() )
- lpddsRender->Restore();
-
- // Check/restore the back buffer
- if( lpddsBackBuffer )
- if( lpddsBackBuffer->IsLost() )
- lpddsBackBuffer->Restore();
- #endif
- return S_OK;
- }
-
- // Moves the screen rect for windowed renderers
- void vOnMove(int x, int y)
- {
- DWORD dwWidth = sRectangle.right - sRectangle.left;
- DWORD dwHeight = sRectangle.bottom - sRectangle.top;
- SetRect( &sRectangle, x, y, x + dwWidth, y + dwHeight );
- }
-
- // Draws the scene. There are three steps here:
- // (1) Animate the scene
- // (2) Render the scene
- // (3) Show the frame (copy backbuffer contents to the Render).
- HRESULT hrRender3DEnvironment(void)
- {
- #ifndef NO3D
- // Call the app specific function to render the scene
- hrRender( lpd3dDevice );
-
- // Show the frame on the Render surface.
- if( DDERR_SURFACELOST == hrShowFrame() )
- hrRestoreSurfaces();
- #endif
- return S_OK;
- }
-
-